#include <p18f2455.h>
#include "HardwareProfile.h"
#include "interrupt.h"
#include "user.h"                              // Modifiable

/** PRIVATE PROTOTYPES *********************************************/

void UserInit(void);
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();

/** V A R I A B L E S ********************************************************/
#pragma udata access interrupt_data

	//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
	//the reset, high priority interrupt, and low priority interrupt
	//vectors.  However, the current Microchip USB bootloader 
	//examples are intended to occupy addresses 0x00-0x7FF or
	//0x00-0xFFF depending on which bootloader is used.  Therefore,
	//the bootloader code remaps these vectors to new locations
	//as indicated below.  This remapping is only necessary if you
	//wish to program the hex file generated from this project with
	//the USB bootloader.  If no bootloader is used, edit the
	//usb_config.h file and comment out the following defines:
	//#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
	//#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
	
	#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
		#define REMAPPED_RESET_VECTOR_ADDRESS			0x1000
		#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1008
		#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1018
	#else	
		#define REMAPPED_RESET_VECTOR_ADDRESS			0x00
		#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x08
		#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x18
	#endif
	
	#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
	extern void _startup (void);        // See c018i.c in your C18 compiler dir
	#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
	void _reset (void)
	{
#ifdef __18CXX
	    _asm goto _startup _endasm
#endif
	}
	#endif
	#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
	void Remapped_High_ISR (void)
	{
		#ifdef __18CXX
		  _asm
		    CALL high_vector_branch, 1
		  _endasm
		#endif
	}
	#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
	void Remapped_Low_ISR (void)
	{
#ifdef __18CXX
	     _asm goto YourLowPriorityISRCode _endasm
#endif
	}
	
	#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
	//Note: If this project is built while one of the bootloaders has
	//been defined, but then the output hex file is not programmed with
	//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
	//As a result, if an actual interrupt was enabled and occured, the PC would jump
	//to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space).  This
	//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
	//(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup".  This
	//would effective reset the application.
	
	//To fix this situation, we should always deliberately place a 
	//"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
	//"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18.  When the output
	//hex file of this project is programmed with the bootloader, these sections do not
	//get bootloaded (as they overlap the bootloader space).  If the output hex file is not
	//programmed using the bootloader, then the below goto instructions do get programmed,
	//and the hex file still works like normal.  The below section is only required to fix this
	//scenario.
	#pragma code HIGH_INTERRUPT_VECTOR = 0x08
	void High_ISR (void)
	{
#ifdef __18CXX
	     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
#endif
	}
	#pragma code LOW_INTERRUPT_VECTOR = 0x18
	void Low_ISR (void)
	{
#ifdef __18CXX
	     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
#endif
	}
	#endif

	#pragma code

	void high_vector_branch(void)
	{
	#ifdef __18CXX
	  _asm
		POP
		GOTO YourHighPriorityISRCode
	  _endasm
	#endif
	}
	
/** I N T E R R U P T  V E C T O R S *****************************************/
	//These are your actual interrupt handling routines.

/** H I G H   I N T E R R U P T *****************************************/
	#pragma interrupt YourHighPriorityISRCode
	void YourHighPriorityISRCode()
	{
		if (PIR1bits.TMR1IF == 1)
		{
			// NOT USED
			PIR1bits.TMR1IF = 0;
		}
		if (INTCONbits.TMR0IF == 1)
		{
                        TMR0H = 0xF8;
                        TMR0L = 0x00;//0xFC;
                        ProcessSweep();
			INTCONbits.TMR0IF = 0;
		}

		#if defined(USB_INTERRUPT)
			USBDeviceTasks();
		#endif
	}	

/** L O W   I N T E R R U P T *******************************************/
	#pragma interruptlow YourLowPriorityISRCode
	void YourLowPriorityISRCode()
	{
		// NOT USED NOW
	}	

